﻿#region File Header

/* File Name    : Comment.cs
 * Description  : A comment on a Graph API object
 * Log
 * Date             Author              Description
 * 16-Oct-2011      Robin Jome          Created the class
 * 19-Oct-2011      Robin Jome          Updated comments
 *                                      Added parameter RSVPStatus to RsvpEvent()
 *                                      Updated all methods with GetUrl()
 */

#endregion

#region Namespaces

using System;
using System.Collections.Generic;
using FacebookAPI.Base;
using FacebookAPI.FacebookProperties;
using FacebookAPI.Objects;

#endregion

namespace FacebookAPI.Managers
{
    #region Class

    /// <summary>
    /// Contains methods to handle Facebook events.
    /// </summary>
    public class FacebookEventManager
    {
        #region Methods

        /// <summary>
        /// Creates a Facebook event
        /// </summary>
        /// <param name="fbEvent">The Facebook Event object</param>
        /// <param name="eventImageFileName">The Event Image file(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the Id of the newly created Facebook Event</returns>
        public string CreateEvent(FacebookEvent fbEvent, string eventImageFileName, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            FacebookBaseObject response = mgr.SaveObject<FacebookBaseObject>(mgr.GetUrl("events", null, accessToken), fbEvent.GetPostData());
            if (response != null && !string.IsNullOrEmpty(eventImageFileName))
            {
                mgr.SaveFile(mgr.GetUrl(response.Id, null, accessToken), new List<string>() { eventImageFileName });
            }
            return (response != null) ? response.Id : null;
        }

        /// <summary>
        /// Updates an existing Facebook event
        /// </summary>
        /// <param name="fbEvent">The Facebook event object</param>
        /// <param name="eventImageFileName">The Event image to be updated</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns true if updated</returns>
        public bool UpdateEvent(FacebookEvent fbEvent, string eventImageFileName, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            bool response = mgr.SaveObject<bool>(mgr.GetUrl(fbEvent.Id, null, accessToken), fbEvent.GetPostData());
            if (!string.IsNullOrEmpty(eventImageFileName))
            {
                mgr.SaveFile(mgr.GetUrl(fbEvent.Id, null, accessToken), new List<string>() { eventImageFileName });
            }
            return response;
        }

        /// <summary>
        /// Gets an Event by its Id
        /// </summary>
        /// <param name="eventId">The Id of the event</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns a Facebook event object</returns>
        public FacebookEvent GetEventById(string eventId, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            return mgr.GetObject<FacebookEvent>(mgr.GetUrl(eventId, null, accessToken));
        }

        /// <summary>
        /// Gets all events related to a Facebook object like user,page
        /// </summary>
        /// <param name="objectId">The Id of the Facebook object</param>
        /// <param name="searchOptions">The search options to be used</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns a list of Facebook events</returns>
        public FacebookConnection<FacebookEvent> GetEvents(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEvent>(objectId, FacebookConnections.Events, searchOptions, accessToken);
        }

        /// <summary>
        /// Invites the specified users to a Facebook event
        /// </summary>
        /// <param name="eventId">The Facebook event id</param>
        /// <param name="userIds">The list of users to be invited</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns true if invitation was successful</returns>
        public bool Invite(string eventId, List<string> userIds, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            return mgr.SaveObject<bool>(mgr.GetUrl(eventId, FacebookConnections.Invited, new FacebookQueryField() { FieldName = "users", FieldValues = userIds }, null, accessToken, false), null);
        }

        /// <summary>
        /// Sets the RSVP status for an event
        /// </summary>
        /// <param name="eventId">The Id of the Event</param>
        /// <param name="status">The RSVP status.</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns true in RSVP is successful</returns>
        public bool RsvpEvent(string eventId, RSVPStatus status, string accessToken)
        {
            if (status == RSVPStatus.NoReply)
            {
                throw new FacebookException("RSVP Status cannot have a value 'NoReply'");
            }

            Nullable<FacebookConnections> connection = null;
            switch (status)
            {
                case RSVPStatus.Attending:
                    connection = FacebookConnections.Attending;
                    break;
                case RSVPStatus.Declined:
                    connection = FacebookConnections.Declined;
                    break;
                case RSVPStatus.MayBe:
                    connection = FacebookConnections.MayBe;
                    break;
            }
            FacebookManager mgr = new FacebookManager();
            return mgr.SaveObject<bool>(mgr.GetUrl(eventId, connection, null, null, accessToken, false));
        }

        /// <summary>
        /// Gets the RSVP status of a user in a Facebook event
        /// </summary>
        /// <param name="eventId">The Event Id</param>
        /// <param name="userId">The User Id</param>
        /// <param name="status">The status to be verified</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns true if participating</returns>
        public bool GetRsvpStatus(string eventId, string userId, RSVPStatus status, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            FacebookConnection<FacebookEventMember> member = mgr.GetConnectionObject<FacebookEventMember>(mgr.GetUrl(eventId + "/" + Enum.GetName(typeof(RSVPStatus), status) + "/" + userId, null, accessToken));
            return (member != null && member.data.Count > 0) ? true : false;
        }

        #endregion

        #region Connections

        /// <summary>
        /// Gets a Facebook connection related to event
        /// </summary>
        /// <typeparam name="T">The type of Facebook connection to be retrieved</typeparam>
        /// <param name="eventId">The Id of the event</param>
        /// <param name="connectionName">The type of connection to be fetched</param>
        /// <param name="searchOptions">The search parameters to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns a list of Facebook connection objects</returns>
        private FacebookConnection<T> GetConnection<T>(string eventId, FacebookConnections connectionName, SearchOptions searchOptions, string accessToken) where T : class
        {
            FacebookManager mgr = new FacebookManager();
            return mgr.GetConnectionObject<T>(mgr.GetUrl(eventId, connectionName, null, searchOptions, accessToken, false));
        }

        /// <summary>
        /// Gets all Posts on the event
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<Post> GetFeed(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<Post>(objectId, FacebookConnections.Feed, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets all invites who haven't responded to the invitation
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<FacebookEventMember> GetNoReplyInvites(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEventMember>(objectId, FacebookConnections.NoReply, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets all invites to an event
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<FacebookEventMember> GetInvitedInvites(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEventMember>(objectId, FacebookConnections.Invited, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets all invites who are attending the event
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<FacebookEventMember> GetAttendingInvites(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEventMember>(objectId, FacebookConnections.Attending, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets all invites who are MayBe the event
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<FacebookEventMember> GetMayBeInvites(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEventMember>(objectId, FacebookConnections.MayBe, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets all invites who are not participating in the event
        /// </summary>
        /// <param name="objectId">The event Id</param>
        /// <param name="searchOptions">Search options to be used(optional)</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the connection object</returns>
        public FacebookConnection<FacebookEventMember> GetDeclinedInvites(string objectId, SearchOptions searchOptions, string accessToken)
        {
            return GetConnection<FacebookEventMember>(objectId, FacebookConnections.Declined, searchOptions, accessToken);
        }

        /// <summary>
        /// Gets the Uri of the event picture
        /// </summary>
        /// <param name="eventId">The Event Id</param>
        /// <param name="accessToken">The Facebook access token</param>
        /// <returns>Returns the Uri of the Facebook event picture</returns>
        public Uri GetPicture(string eventId, string accessToken)
        {
            FacebookManager mgr = new FacebookManager();
            return new Uri(mgr.GetObject<string>(mgr.GetUrl(eventId, FacebookConnections.Picture, accessToken)));
        }

        #endregion
    }

    #endregion
}
